/*
 * ServidorQualidade.java
 *
 * Criado em 30 de Maio de 2007, 16:22
 *
 */

package qvoipm.sistema;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import qvoipm.base.BD;
import qvoipm.dados.Fim;
import qvoipm.dados.Pacote;
import qvoipm.dados.Qualidade;

/**
 *
 * @author Rodrigo
 */
public class ServidorQualidade implements Runnable{
    
    public int porta;
    private boolean rodando;
    
    public ServidorQualidade(int porta) {
	this.porta = porta;
    }
    
    /**
     * Manda o servidor parar, mas nao
     * garante que vai parar ja que
     * pode estar preso em uma tentativa
     * de conexao
     */
    public void parar() {
	rodando = false;
    }
    
    public void run() {
	
	ServerSocket serverSocket = null;
	Socket socket;
	InputStream in;
	OutputStream out;
	
	/* Cria buffers */
	byte bufferQualidade[] = new byte[Qualidade.SIZE];
	byte bufferFim[] = new byte[Fim.SIZE];
	
	/* Cria pacotes */
	Qualidade qualidade = new Qualidade();
	Fim fim = new Fim();
	
	try {
	    serverSocket = new ServerSocket(porta);
	} catch (IOException ex) {
	    ex.printStackTrace();
	    return;
	}
	
	try {
	    
	    /* loop infinito */
	    rodando = true;
	    
	    while (rodando) {
		
		/* conecta-se com um cliente */
		socket = serverSocket.accept();
		
		/* Cria reader */
		in = socket.getInputStream();
		/* Cria writer */
		out = socket.getOutputStream();
		
		/* le primeiro byte */
		int id = in.read();
		switch (id) {
		    case Qualidade.ID:
			/* Le e cria pacote */
			in.read(bufferQualidade);
			qualidade.fromBytes(bufferQualidade, false);
			
			/* Verifica se esta aberta a chamada */
			switch (BD.statusChamada(qualidade.getChamada())) {
			    case BD.ABERTA:
				BD.inserirQualidade(qualidade);
				break;
			    case BD.FECHADA:
				System.err.println("QVOIPM: Qualidade: Pacote qualidade: Chamada fechada: " + qualidade.getChamada());
				System.err.println("Cliente: " + socket.getRemoteSocketAddress());
				break;
			    case BD.INEXISTENTE:
				System.err.println("QVOIPM: Qualidade: Pacote qualidade: Chamada inexistente: " + fim.getChamada());
				System.err.println("Cliente: " + socket.getRemoteSocketAddress());
				break;
			}
			break;
		    case Fim.ID:
			
			/* Le e cria pacote */
			in.read(bufferFim);
			fim.fromBytes(bufferFim,  false);
			
			/* Verifica se esta aberta a chamada */
			switch (BD.statusChamada(fim.getChamada())) {
			    case BD.ABERTA:
				BD.fecharChamada(fim);
				break;
			    case BD.FECHADA:
				System.err.println("QVOIPM: Qualidade: Pacote fim: Chamada fechada: " + fim.getChamada());
				System.err.println("Cliente: " + socket.getRemoteSocketAddress());
				break;
			    case BD.INEXISTENTE:
				System.err.println("QVOIPM: Qualidade: Pacote fim: Chamada inexistente: " + fim.getChamada());
				System.err.println("Cliente: " + socket.getRemoteSocketAddress());
				break;
			}
			
			break;
		    case Pacote.TERMINAR_SERVIDOR:
			rodando=false;
			break;
		    default:
			System.err.println("QVOIPM: Qualidade: Pacote " + id + " recebido do cliente invalido.");
			System.err.println("Cliente: " + socket.getRemoteSocketAddress());
		}
		
		/* desconecta */
		in.close();
		out.close();
		socket.close();
		
		/* Coleta lixo */
		System.gc();
	    }
	    
	} catch (IOException ex) {
	    ex.printStackTrace();
	}
	
    }
    
}
